#include "server.h"

// 生成socket套接字
int create_sock()
{
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(8999);
    addr.sin_addr.s_addr = inet_addr("172.29.94.233");
    int res = 0;
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == -1)
    {
        printf("socket creation failed\n");
        return -1;
    }
    res = bind(sock, (struct sockaddr *)&addr, sizeof(addr));
    {
        if (res == -1)
        {
            printf("bind failed\n");
            return -1;
        }
    }
    res = listen(sock, 5);
    if (res == -1)
    {
        printf("listen failed\n");
        return -1;
    }
    return sock;
}

// 监听
void *epoll_listen(void *arg)
{
    struct epoll_event ev, events[MAX_EVENTS];
    int count;
    int res;
    char buf[1024];
    int sock = create_sock();
    model *p = (QUE *)arg;
    if (sock == -1)
    {
        printf("socket creation failed\n");
        return -1;
    }
    int epollfd = epoll_create1(0);
    if (epollfd == -1)
    {
        printf("epoll creation failed\n");
        return -1;
    }
    // 将监听socket加入epoll实例
    ev.data.fd = sock;
    ev.events = EPOLLIN;
    res = epoll_ctl(epollfd, EPOLL_CTL_ADD, sock, &ev);
    if (res == -1)
    {
        printf("epoll_ctl failed\n");
        return -1;
    }
    while (1)
    {
        count = epoll_wait(epollfd, events, MAX_EVENTS, -1);
        if (res == -1)
        {
            printf("epoll_wait failed\n");
            return -1;
        }
        for (int i = 0; i < count; i++)
        {
            if (events[i].data.fd == sock)
            {
                int sockfd = accept(sock, NULL, NULL);
                if (sockfd == -1)
                {
                    perror("accept");
                    exit(1);
                }
                setnonblocking(sockfd);
                ev.data.fd = sockfd;
                ev.events = EPOLLIN;
                res = epoll_ctl(epollfd, EPOLL_CTL_ADD, sockfd, &ev);
                if (res == -1)
                {
                    perror("epoll_ctl");
                    exit(1);
                }
            }
            else
            {
                res = recv(events[i].data.fd, buf, 1024, 0);
                if (res == -1)
                {
                    perror("recv");
                    exit(1);
                }
                sem_wait(&p->semw);
                pthread_mutex_lock(&p->lock);
                push(events[i].data.fd,buf,que);
                pthread_mutex_unlock(&p->lock);
                sem_post(&p->semr);
            }
        }
    }
}

void *custumor(void *arg)
{
    model *p = (QUE *)arg;
    sem_wait(&p->semr);
    pthread_mutex_lock(&p->lock);
    QUE new = pop(que);
    pthread_mutex_unlock(&p->lock);
    sem_post(&p->semw);

    unsigned long data_len = strlen(new.data.function);
    All *all_msg = all__unpack(NULL, data_len, new.data.function);
    if (all_msgs == NULL) {
        fprintf(stderr, "Failed to unpack 'All' message.\n");
    }
    if(strcmp(all_msh->type,"login")==0){
        Login *login_msh = login__unpack(NULL, all_msh->payload.len, all_msh->payload.data);
        if (login_msh == NULL)
        {
            printf("Failed to unpack 'Login' message.\n");
            printf("login_msh->type:%s\n",login_msh->user);
        }

    }
    // 2. 打印消息类型
    printf("Decoded 'All' message:\n");
    printf("  Message Type: %s\n", all_msh->type);
    Inf *end=inf__unpack(NULL,all_msh->payload.len,all_msh->payload.data);
    printf("%d\n",end->num1);
    printf("%d\n",end->num2);
}
//将套接字设为非阻塞状态非阻塞
int setnonblocking(int fd)
{
    int old_option = fcntl(fd, F_GETFL);
    int new_option = old_option | O_NONBLOCK;
    fcntl(fd, F_SETFL, new_option);
    return old_option;
}
